home *** CD-ROM | disk | FTP | other *** search
/ Merciful 2 / Merciful - Disc 2.iso / software / d / devioustools19.dms / devioustools19.adf / utils / 010.lzx / Flush / Flush.c < prev    next >
C/C++ Source or Header  |  1987-01-06  |  9KB  |  350 lines

  1. /*
  2.  * Flush
  3.  * Selectively remove unused libraries, devices and fonts from memory.
  4.  *
  5.  * Written by Septh (Stephan Schreiber)
  6.  */
  7.  
  8. #include <string.h>
  9. #include <exec/types.h>
  10. #include <exec/nodes.h>
  11. #include <exec/lists.h>
  12. #include <exec/memory.h>
  13. #include <exec/libraries.h>
  14. #include <exec/devices.h>
  15. #include <exec/execbase.h>
  16. #include <dos/dos.h>
  17. #include <dos/dosasl.h>
  18. #include <graphics/text.h>
  19. #include <graphics/gfxbase.h>
  20.  
  21. #include <clib/exec_protos.h>
  22. #include <clib/dos_protos.h>
  23. #include <clib/graphics_protos.h>
  24.  
  25. #include <pragmas/exec_sysbase_pragmas.h>
  26. #include <pragmas/dos_pragmas.h>
  27. #include <pragmas/graphics_pragmas.h>
  28.  
  29. /******************************************************************************
  30.  * Constants and macros
  31.  ******************************************************************************/
  32. #define    TEMPLATE    "NAMES/M,LIBS=LIBRARIES/S,DEVS=DEVICES/S,FONTS/S,ALL/S,QUIET/S"
  33. enum
  34. {    OPT_NAMES = 0,    // Name(s) of libs/devs/fonts to flush
  35.     OPT_LIBS,        // Limit flush to libraries
  36.     OPT_DEVS,        // Limit flush to devices
  37.     OPT_FONTS,        // Limit flush to fonts
  38.     OPT_ALL,        // Flush libs, devs AND fonts
  39.     OPT_QUIET,        // Shut up!
  40.     NUM_OPTS
  41. };
  42.  
  43. /* Short-cuts */
  44. #define    lib_Succ    lib_Node.ln_Succ
  45. #define    lib_Name    lib_Node.ln_Name
  46.  
  47. #define    dd_Succ        dd_Library.lib_Node.ln_Succ
  48. #define    dd_Name        dd_Library.lib_Node.ln_Name
  49.  
  50. #define    tf_Succ        tf_Message.mn_Node.ln_Succ
  51. #define    tf_Name        tf_Message.mn_Node.ln_Name
  52.  
  53. /******************************************************************************
  54.  * Globals
  55.  ******************************************************************************/
  56. UBYTE *version = "\0$VER: Flush 1.0 (30.10.95)";
  57.  
  58. struct Library *SysBase;
  59. struct Library *DOSBase;
  60. struct Library *GfxBase;
  61.  
  62. UBYTE *def_names[] =
  63. {    "#?",
  64.     NULL
  65. };
  66.  
  67. /******************************************************************************
  68.  * Prototypes
  69.  ******************************************************************************/
  70. VOID flush_fonts(UBYTE **names, LONG quiet);
  71. VOID flush_devs(UBYTE **names, LONG quiet);
  72. VOID flush_libs(UBYTE **names, LONG quiet);
  73.  
  74. /******************************************************************************
  75.  * Program entry point
  76.  ******************************************************************************/
  77. LONG __saveds main(UBYTE *cmdline)
  78. {
  79. struct Process *me;
  80. struct Message *wbmsg;
  81. struct RDArgs *rda;
  82. ULONG opts[NUM_OPTS];
  83.  
  84.     /* Get SysBase */
  85.     SysBase = *((struct Library **)4L);
  86.  
  87.     /* Minimal WB startup */
  88.     me = (struct Process *)FindTask(NULL);
  89.     if (me->pr_CLI == NULL)
  90.     {    WaitPort(&me->pr_MsgPort);
  91.         wbmsg = GetMsg(&me->pr_MsgPort);
  92.     }
  93.     else wbmsg = NULL;
  94.  
  95.     /* Open the libraries */
  96.     if (DOSBase= OpenLibrary("dos.library", 37L))
  97.     {    if (GfxBase = OpenLibrary("graphics.library", 0L))
  98.         {    /* When run under Workbench,
  99.              * no arguments are usable.
  100.              */
  101.             if (wbmsg)
  102.             {    flush_fonts(def_names, TRUE);
  103.                 flush_devs(def_names, TRUE);
  104.                 flush_libs(def_names, TRUE);
  105.             }
  106.             else
  107.             {    /* Get shell arguments */
  108.                 memset(opts, '\0', sizeof(opts));
  109.                 rda = ReadArgs(TEMPLATE, opts, NULL);
  110.  
  111.                 /* Break ? */
  112.                 if (CheckSignal(SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
  113.                 {    if (rda)
  114.                     {    FreeArgs(rda);
  115.                         rda = NULL;
  116.                     }
  117.                     SetIoErr(ERROR_BREAK);
  118.                 }
  119.  
  120.                 if (rda)
  121.                 {    /* ALL ? */
  122.                     if (opts[OPT_ALL] || (!opts[OPT_LIBS] && !opts[OPT_DEVS] && !opts[OPT_FONTS]))
  123.                     {    opts[OPT_LIBS]  = DOSTRUE;
  124.                         opts[OPT_DEVS]  = DOSTRUE;
  125.                         opts[OPT_FONTS] = DOSTRUE;
  126.                     }
  127.  
  128.                     /* Here we begin with fonts for aesthetics reasons:
  129.                      * if we flushed the libraries before the fonts,
  130.                      * then we could not report which fonts would get flushed.
  131.                      * This is because when flushed, diskfont.library
  132.                      * simply removes all unsued fonts still in memory.
  133.                      */
  134.  
  135.                     /* FONTS ? */
  136.                     if (opts[OPT_FONTS])
  137.                         flush_fonts((UBYTE **)opts[OPT_NAMES], opts[OPT_QUIET]);
  138.  
  139.                     /* These two could use a single function... */
  140.                     /* DEVS ? */
  141.                     if (opts[OPT_DEVS])
  142.                         flush_devs((UBYTE **)opts[OPT_NAMES], opts[OPT_QUIET]);
  143.  
  144.                     /* LIBS ? */
  145.                     if (opts[OPT_LIBS])
  146.                         flush_libs((UBYTE **)opts[OPT_NAMES], opts[OPT_QUIET]);
  147.  
  148.                     FreeArgs(rda);
  149.                 }
  150.                 else PrintFault(IoErr(), NULL);
  151.             }
  152.             CloseLibrary(GfxBase);
  153.         }
  154.         CloseLibrary(DOSBase);
  155.     }
  156.  
  157.     /* Back to WB ? */
  158.     if (wbmsg)
  159.     {    Forbid();
  160.         ReplyMsg(wbmsg);
  161.     }
  162.  
  163.     return(RETURN_OK);
  164. }
  165.  
  166. /******************************************************************************
  167.  * Flush unused fonts
  168.  ******************************************************************************/
  169. VOID flush_fonts(UBYTE **names, LONG quiet)
  170. {
  171. struct List *fonts_list;
  172. struct TextFont *font;
  173. UBYTE pat[256], font_name[256];
  174. UWORD font_size;
  175. struct TextFont *tmp_font;
  176.  
  177.     /* Get the fonts list */
  178.     fonts_list = &(((struct GfxBase *)GfxBase)->TextFonts);
  179.  
  180.     if (names == NULL)
  181.         names = def_names;
  182.  
  183.     while (*names)
  184.     {    /* Allow for wildcards in names */
  185.         ParsePatternNoCase(*names++, pat, sizeof(pat));
  186.  
  187.         Forbid();
  188.  
  189.         /* Font each font in the system... */
  190.         for (font = (struct TextFont *)fonts_list->lh_Head; font->tf_Succ; font = (struct TextFont *)font->tf_Succ)
  191.         {    /* Check number of accessors of this font
  192.              * See if name matches
  193.              */
  194.             if ((font->tf_Accessors == 0) && MatchPatternNoCase(pat, font->tf_Name))
  195.             {    /* Copy name in temp buffer */
  196.                 strcpy(font_name, font->tf_Name);
  197.  
  198.                 /* Copy font size, too */
  199.                 font_size = font->tf_YSize;
  200.  
  201.                 /* Ok, let's flush it */
  202.                 StripFont(font);    // Fonts won't flush without this!
  203.                 RemFont(font);
  204.  
  205.                 /* Check if it really flushed */
  206.                 tmp_font = (struct TextFont *)fonts_list;
  207.                 while (tmp_font = (struct TextFont *)FindName((struct List *)tmp_font, font_name))
  208.                 {    if (tmp_font == font)
  209.                         break;
  210.                 }
  211.  
  212.                 if (tmp_font == NULL)
  213.                 {    /* Tell them it's done */
  214.                     if (!quiet)
  215.                     {    Permit();
  216.                         Printf("font \"%s\", size %ld flushed\n", font_name, font_size);
  217.                         Forbid();
  218.                     }
  219.  
  220.                     /* Go back to start of list.
  221.                      * Note that because we are in a for() loop,
  222.                      * the 'font = font->tf_Succ' statement
  223.                      * will be executed *after* this one.
  224.                      * So we have to make 'font' point to
  225.                      * the list header rather than to the head node,
  226.                      * or we'll miss the first font in the list.
  227.                      */
  228.                     font = (struct TextFont *)fonts_list;
  229.                 }
  230.             }
  231.         }
  232.     }
  233. }
  234.  
  235. /******************************************************************************
  236.  * Flush unused devices
  237.  ******************************************************************************/
  238. VOID flush_devs(UBYTE **names, LONG quiet)
  239. {
  240. struct List *devs_list;
  241. struct Device *dev;
  242. UBYTE pat[256], dev_name[256];
  243.  
  244.     /* Get the devices list */
  245.     devs_list = &(((struct ExecBase *)SysBase)->DeviceList);
  246.  
  247.     if (names == NULL)
  248.         names = def_names;
  249.  
  250.     while (*names)
  251.     {    /* Allows for wildcards in names */
  252.         ParsePatternNoCase(*names++, pat, sizeof(pat));
  253.  
  254.         Forbid();
  255.  
  256.         /* for each device in the list... */
  257.         for (dev = (struct Device *)devs_list->lh_Head; dev->dd_Succ; dev = (struct Device *)dev->dd_Succ)
  258.         {    /* Check opencount of this device.
  259.              * See if name matches.
  260.              */
  261.             if ((dev->dd_Library.lib_OpenCnt == 0) && MatchPatternNoCase(pat, dev->dd_Name))
  262.             {    /* Copy name in temp buffer */
  263.                 strcpy(dev_name, dev->dd_Name);
  264.  
  265.                 /* Ok, let's flush it */
  266.                 RemDevice(dev);
  267.  
  268.                 /* Check if it really flushed */
  269.                 if (FindName(devs_list, dev_name) == NULL)
  270.                 {    /* Tell them it's done */
  271.                     if (!quiet)
  272.                     {    Permit();
  273.                         Printf("Device \"%s\" flushed\n", dev_name);
  274.                         Forbid();
  275.                     }
  276.  
  277.                     /* Go back to start of list.
  278.                      * Note that because we are in a for() loop,
  279.                      * the 'dev = dev->dd_Succ' statement
  280.                      * will be executed *after* this one.
  281.                      * So we have to make 'dev' point to
  282.                      * the list header rather than to the head node,
  283.                      * or we'll miss the first device in the list.
  284.                      */
  285.                     dev = (struct Device *)devs_list;
  286.                 }
  287.             }
  288.         }
  289.         Permit();
  290.     }
  291. }
  292.  
  293. /******************************************************************************
  294.  * Flush unused libraries
  295.  ******************************************************************************/
  296. VOID flush_libs(UBYTE **names, LONG quiet)
  297. {
  298. struct List *libs_list;
  299. struct Library *lib;
  300. UBYTE pat[256], lib_name[256];
  301.  
  302.     /* Get the libraries list */
  303.     libs_list = &(((struct ExecBase *)SysBase)->LibList);
  304.  
  305.     if (names == NULL)
  306.         names = def_names;
  307.  
  308.     while (*names)
  309.     {    /* Allows for wildcards in names */
  310.         ParsePatternNoCase(*names++, pat, sizeof(pat));
  311.  
  312.         Forbid();
  313.  
  314.         /* for each library in the system... */
  315.         for (lib = (struct Library *)libs_list->lh_Head; lib->lib_Succ; lib = (struct Library *)lib->lib_Succ)
  316.         {    /* Check opencount of this library.
  317.              * See if name matches.
  318.              */
  319.             if ((lib->lib_OpenCnt == 0) && MatchPatternNoCase(pat, lib->lib_Name))
  320.             {    /* Copy name in temp buffer */
  321.                 strcpy(lib_name, lib->lib_Name);
  322.  
  323.                 /* Ok, let's flush it */
  324.                 RemLibrary(lib);
  325.  
  326.                 /* Check if it really flushed */
  327.                 if (FindName(libs_list, lib_name) == NULL)
  328.                 {    /* Tell them it's done */
  329.                     if (!quiet)
  330.                     {    Permit();
  331.                         Printf("Library \"%s\" flushed\n", lib_name);
  332.                         Forbid();
  333.                     }
  334.  
  335.                     /* Go back to start of list.
  336.                      * Note that because we are in a for() loop,
  337.                      * the 'lib = lib->lib_Succ' statement
  338.                      * will be executed *after* this one.
  339.                      * So we have to make 'lib' point to
  340.                      * the list header rather than to the head node,
  341.                      * or we'll miss the first library in the list.
  342.                      */
  343.                     lib = (struct Library *)libs_list;
  344.                 }
  345.             }
  346.         }
  347.         Permit();
  348.     }
  349. }
  350.